﻿using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using DingTalk.Common;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace DingWebIService
{
    public class DingDALService : IDingDALRepository
    {
        private readonly IRedisBasketRepository _cache;
        private readonly ILogger _logger;
        public DingDALService(ILogger logger, IRedisBasketRepository cache)
        {
            _logger = logger;
            _cache = cache;
        }

        /// <summary>
        /// 获取token
        /// </summary>  
        [HttpGet]
        public async Task<OapiGettokenResponse> GetAccessToken(string appkey, string appsecret)
        {
            //_cache.Remove("DingdingAccessToken").Wait(); 
            OapiGettokenResponse response = new OapiGettokenResponse();
            try
            {
                try
                {
                    OapiGettokenResponse res = await _cache.Get<OapiGettokenResponse>("DingdingAccessToken");
                    if (res != null && !string.IsNullOrWhiteSpace(res.AccessToken))
                    {
                        return res;
                    }
                }
                catch (Exception ex)
                {
                    // 如果redis报错就忽略
                    _logger.LogDebug("redis:" + ex.ToString());
                    _logger.LogInformation("Redis报错了，请尽快修复");
                }

                IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
                OapiGettokenRequest request = new OapiGettokenRequest();
                request.Appkey = appkey;
                request.Appsecret = appsecret;
                request.SetHttpMethod("GET");
                response = client.Execute(request);
                if (response.Errcode == 0)
                {
                    _cache.Set("DingdingAccessToken", response, TimeSpan.FromHours(1.5)).Wait();
                    return response;
                }
            }
            catch (Exception ex)
            {
                _logger.LogDebug("GetAccessToken:" + ex.ToString());

                if (response.Errcode == 0)
                {
                    return response;
                }
            }
            return response;
        }

        #region 获取用户信息，创建修改 
        /// <summary>
        /// 根据unionid获取userid
        /// </summary>
        /// <param name="unionid">unionid是员工在当前开发者企业账号范围内的唯一标识，由系统生成</param>
        /// <param name="accesstoken">token</param>
        /// <returns></returns>
        [HttpPost]
        public OapiUserGetbyunionidResponse getUseridByUnionid(string unionid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
            OapiUserGetbyunionidRequest request = new OapiUserGetbyunionidRequest();
            request.Unionid = unionid;
            OapiUserGetbyunionidResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 根据手机号获取用户id
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns> 
        [HttpPost]
        public OapiV2UserGetbymobileResponse GetByMobile(string mobile, string accesstoken)
        {
            OapiV2UserGetbymobileResponse response = new OapiV2UserGetbymobileResponse();
            if (string.IsNullOrWhiteSpace(mobile) || mobile.Length != 11)
            {
                response.ErrMsg = "手机号 必填";
                return response;
            }

            if (string.IsNullOrWhiteSpace(accesstoken))
            {
                response.ErrMsg = "accesstoken 必填";
                return response;
            }
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest request = new OapiV2UserGetbymobileRequest();
            request.Mobile = mobile;
            response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 未登录钉钉的员工列表
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>3
        [HttpPost]
        public OapiInactiveUserV2GetResponse GetUnlogin(string date, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/inactive/user/v2/get");
            OapiInactiveUserV2GetRequest request = new OapiInactiveUserV2GetRequest();

            request.IsActive = false;//false 未登录  true 登录

            // 分页偏移量 
            request.Offset = 0L;
            // 每页size，最多100 
            request.Size = 100L;
            // 查询日期 
            request.QueryDate = date;// ("20190903");

            OapiInactiveUserV2GetResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="mobile"></param>
        /// <param name="name"></param>
        /// <param name="departmentids"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiUserCreateResponse CreateUser(string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/create");
            OapiUserCreateRequest request = new OapiUserCreateRequest();
            //request.Userid = userid;
            //request.Mobile = mobile;
            //request.Name = name;
            //// 需要用字符串， "[100,200]" 这种格式 
            ////List<long> departments = new List<long>(); 
            ////departments.add(100L); 
            ////departments.add(200L);

            //request.Department = departmentids;
            OapiUserCreateResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserUpdateResponse UpdateUser(string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update");
            OapiV2UserUpdateRequest request = new OapiV2UserUpdateRequest();
            request.Userid = "zhangsan";
            request.Name = "张三";
            request.HideMobile = false;
            request.Telephone = "010-86123456-2345";
            request.JobNumber = "4";
            request.Title = "技术总监";
            request.Email = "test@xxx.com";
            request.WorkPlace = "未来park";
            request.Remark = "备注备注";
            request.DeptIdList = "2,3,4";
            OapiV2UserUpdateResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        [HttpPost]
        public OapiV2UserDeleteResponse DeleteUser(string userid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/delete");
            OapiV2UserDeleteRequest request = new OapiV2UserDeleteRequest();
            request.Userid = userid;
            OapiV2UserDeleteResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 根据用户id获取用户信息
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2UserGetResponse GetUser(string userid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest request = new OapiV2UserGetRequest();
            request.Userid = userid;
            request.Language = "zh_CN";
            OapiV2UserGetResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 获取部门获取用户信息
        /// </summary>
        /// <param name="departmentId">部门id</param>
        /// <param name="size">分页大小，最大100</param>
        /// <returns></returns>
        [HttpPost]
        public OapiUserSimplelistResponse GetSimplelist(long departmentId, long size, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
            OapiUserSimplelistRequest request = new OapiUserSimplelistRequest();
            request.DepartmentId = departmentId;
            request.Offset = 0L;
            request.Size = size;
            request.Order = "entry_desc"; //entry_asc 升序

            request.SetHttpMethod("GET");
            OapiUserSimplelistResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

        #region 部门信息，子部门信息
        /// <summary>
        /// 获取部门信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public OapiV2DepartmentListsubResponse GetDepartment(int deptid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest();
            request.DeptId = deptid;
            OapiV2DepartmentListsubResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 获取子部门ID列表 1所有二级部门
        /// </summary>
        /// <param name="deptid"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiV2DepartmentListsubidResponse GetDepartmentById(int deptid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsubid");
            OapiV2DepartmentListsubidRequest request = new OapiV2DepartmentListsubidRequest();
            request.DeptId = deptid;
            OapiV2DepartmentListsubidResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

        #region 工作通知
        /// <summary>
        /// 发送工作通知
        /// </summary> 
        /// <param name="msg">https://open.dingtalk.com/document/orgapp-server/asynchronous-sending-of-enterprise-session-messages</param>
        /// <param name="agentid"></param>
        /// <param name="useridlist"></param>
        /// <param name="accesstoken"></param>
        /// <param name="toalluser"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiMessageCorpconversationAsyncsendV2Response MessageSend(string msg, int agentid, string useridlist, string accesstoken, bool toalluser = false)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.AgentId = agentid;
            request.UseridList = useridlist;// "user123";
            request.ToAllUser = toalluser;

            //object request = new
            //{
            //object msg = new
            //{
            //    voice = new
            //    {
            //        duration = "100",
            //        media_id = "100"
            //    },
            //    image = new
            //    {
            //        media_id = "@123"
            //    },
            //    oa = new
            //    {
            //        head = new
            //        {
            //            bgcolor = "bgcolor",
            //            text = "text"
            //        },
            //        pc_message_url = "pc_message_url",
            //        status_bar = new
            //        {
            //            status_value = "进行中",
            //            status_bg = "0xFFF65E5E"
            //        },
            //        body = new
            //        {
            //            file_count = "file_count",
            //            image = "image",
            //            form = new
            //            {
            //                value = "value",
            //                key = "key"
            //            },
            //            author = "author",
            //            rich = new
            //            {
            //                unit = "unit",
            //                num = "num"
            //            },
            //            title = "title",
            //            content = "content"
            //        },
            //        message_url = "message_url"
            //    },
            //    file = new
            //    {
            //        media_id = "media_id"
            //    },
            //    action_card = new
            //    {
            //        btn_json_list = new
            //        {
            //            action_url = "action_url",
            //            title = "title"
            //        },
            //        single_url = "single_url",
            //        btn_orientation = "btn_orientation",
            //        single_title = "single_title",
            //        markdown = "markdown",
            //        title = "title"
            //    },
            //    link = new
            //    {
            //        picUrl = "picUrl",
            //        messageUrl = "messageUrl",
            //        text = "text",
            //        title = "title"
            //    },
            //    markdown = new
            //    {
            //        text = "text",
            //        title = "title"
            //    },
            //    text = new
            //    {
            //        content = "123"
            //    },
            //    msgtype = "text"
            //};
            //    to_all_user = "false",
            //    agent_id = "123",
            //    dept_id_list = "123,456",
            //    userid_list = "123,456"
            //};

            request.Msg = msg;
            OapiMessageCorpconversationAsyncsendV2Response response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 更新工作通知状态栏
        /// </summary> 
        /// <param name="statusvalue">https://open.dingtalk.com/document/orgapp-server/update-work-notification-status-bar</param>
        /// <param name="agentid"></param>
        /// <param name="TaskId"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        [HttpPost]
        public OapiMessageCorpconversationStatusBarUpdateResponse MessageUpdate(string statusvalue, int agentid, int TaskId, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/status_bar/update");
            OapiMessageCorpconversationStatusBarUpdateRequest request = new OapiMessageCorpconversationStatusBarUpdateRequest();
            request.AgentId = agentid;
            request.StatusValue = statusvalue;// "已同意";
            request.StatusBg = "0xFF78C06E";
            request.TaskId = TaskId;
            OapiMessageCorpconversationStatusBarUpdateResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }

        /// <summary>
        /// 撤销工作通知
        /// </summary>
        [HttpPost]
        public OapiMessageCorpconversationRecallResponse MessageBack(int agentid, int msgtaskid, string accesstoken)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/recall");
            OapiMessageCorpconversationRecallRequest request = new OapiMessageCorpconversationRecallRequest();
            request.AgentId = agentid;
            request.MsgTaskId = msgtaskid;
            OapiMessageCorpconversationRecallResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                _logger.LogDebug(response.ErrMsg);
                return response;
            }
            response.ErrMsg = "失败";
            return response;
        }
        #endregion

    }
}
